package com.kh.rationaldrugreview.neo4j.repository;

import com.kh.rationaldrugreview.neo4j.entity.DrugNode;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.data.neo4j.repository.query.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@Repository
public interface DrugNodeRepository extends Neo4jRepository<DrugNode, Long> {
    
    Optional<DrugNode> findByDrugCode(String drugCode);
    
    List<DrugNode> findByDrugNameContaining(String drugName);
    
    List<DrugNode> findByActiveIngredientContaining(String activeIngredient);
    
    List<DrugNode> findByCategory(String category);
    
    @Query("MATCH (d1:Drug)-[r:INTERACTS_WITH]->(d2:Drug) WHERE d1.drugCode = $drugCode RETURN d2, r")
    List<DrugNode> findInteractingDrugs(@Param("drugCode") String drugCode);
    
    @Query("MATCH (d1:Drug {drugCode: $drugCode1})-[r:INTERACTS_WITH]->(d2:Drug {drugCode: $drugCode2}) RETURN r")
    Object findInteractionBetweenDrugs(@Param("drugCode1") String drugCode1, @Param("drugCode2") String drugCode2);
    
    @Query("MATCH (d:Drug) WHERE d.contraindication CONTAINS $condition RETURN d")
    List<DrugNode> findDrugsContraindicatedFor(@Param("condition") String condition);
    
    @Query("MATCH (d:Drug) WHERE d.indication CONTAINS $indication RETURN d")
    List<DrugNode> findDrugsForIndication(@Param("indication") String indication);
    
    @Query("MATCH (d1:Drug)-[r:INTERACTS_WITH]->(d2:Drug) WHERE r.severity = $severity RETURN d1, r, d2")
    List<Object> findInteractionsBySeverity(@Param("severity") String severity);
    
    @Query("MATCH (d:Drug) WHERE d.activeIngredient = $ingredient RETURN d")
    List<DrugNode> findDrugsByExactActiveIngredient(@Param("ingredient") String ingredient);
    
    @Query("MERGE (d:Drug {name: $drugName}) " +
           "MERGE (i:Indication {name: $indication}) " +
           "MERGE (d)-[:INDICATED_FOR]->(i)")
    void addIndicationRelationship(@Param("drugName") String drugName, 
                                  @Param("indication") String indication);
    
    @Query("MERGE (d:Drug {name: $drugName}) " +
           "MERGE (c:Contraindication {name: $contraindication}) " +
           "MERGE (d)-[:CONTRAINDICATED_FOR]->(c)")
    void addContraindicationRelationship(@Param("drugName") String drugName, 
                                        @Param("contraindication") String contraindication);
    
    @Query("MERGE (d1:Drug {name: $drug1Name}) " +
           "MERGE (d2:Drug {name: $drug2Name}) " +
           "MERGE (d1)-[r:INTERACTS_WITH {severity: $severity, effect: $effect}]->(d2)")
    void addDrugInteraction(@Param("drug1Name") String drug1Name, 
                           @Param("drug2Name") String drug2Name,
                           @Param("severity") String severity,
                           @Param("effect") String effect);
    
    // Note: Dynamic labels and relationship types are not directly supported in @Query
    // These methods should be implemented using Neo4jClient or Driver directly
    default void createNode(String nodeType, Map<String, Object> properties) {
        // This should be implemented in a service using Neo4jClient
        throw new UnsupportedOperationException("Use Neo4jCypherService for dynamic node creation");
    }
    
    default void createRelationship(String sourceName, String targetName, 
                                   String relType, Map<String, Object> properties) {
        // This should be implemented in a service using Neo4jClient
        throw new UnsupportedOperationException("Use Neo4jCypherService for dynamic relationship creation");
    }
}